package feizhou.untils.tools;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 时间工具
 *
 * @author <a href="920786312@qq.com">周飞</a>
 * @since 2023/8/23 18:48
 */
public class DateUtil {
    private static final Log logger = LogFactory.getLog(DateUtil.class);

    public static final String YYYYMMDD = "yyyy-MM-dd";



    public static final int FIRST_DAY_OF_WEEK = Calendar.MONDAY; // 中国周一是一周的第一天

    public static final String DATETIME = "yyyy-MM-dd HH:mm:ss";

    public static final String DATETIMEOUT = "yyyyMMddHHmmss";


    private static final String DATETIME_UTC = "yyyy-MM-dd'T'HH:mm:ss'Z'";

    private static final String DATETIME_UTC_FULL = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";


    public static final String ASC = "asc";

    public static final String DESC = "desc";

    private static List<String> weekend = new ArrayList<String>();

    private static final DateFormat dateTimeFormatter = new SimpleDateFormat(DATETIME);

    public static final int SECONDS_IN_DAY = 60 * 60 * 24;

    public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;

    public static final long eight_hour = 8 * 3600 * 1000;

    //默认时区信息
    public static final String CHINA_TIMEZONE = "GMT+8:00";

    public static long time2005 = parse("yyyy-MM-dd HH:mm:ss", "2005-01-01 00:00:00").getTime();
    public static long time1999 = parse("yyyy-MM-dd HH:mm:ss", "1999-12-01 00:00:00").getTime();

    static {
        weekend.add("Sun");
        weekend.add("Sat");
        weekend.add("星期六");
        weekend.add("星期日");
    }

    /**
     * 一小时的秒数
     */
    private static final int HOUR_SECOND = 60 * 60;

    /**
     * 一分钟的秒数
     */
    private static final int MINUTE_SECOND = 60;

    /**
     * 根据秒数获取时间串
     *
     * @param second (eg: 100s)
     * @return (eg : 00 : 01 : 40)
     */
    public static String getTimeStrBySecond(int second) {
        if (second <= 0) {

            return "00:00:00";
        }

        StringBuilder sb = new StringBuilder();
        int hours = second / HOUR_SECOND;
        if (hours > 0) {

            second -= hours * HOUR_SECOND;
        }

        int minutes = second / MINUTE_SECOND;
        if (minutes > 0) {

            second -= minutes * MINUTE_SECOND;
        }

        return (hours >= 10 ? ((hours + "") + ":" + (minutes >= 10 ? (minutes + "") : ("0" + minutes)) + ":"
                + (second >= 10 ? (second + "") : ("0" + second)))
                : ("0" + hours) + ":" + (minutes >= 10 ? (minutes + "") : ("0" + minutes)) + ":"
                + (second >= 10 ? (second + "") : ("0" + second)));
    }

    /**
     * 获取周几
     *
     * @return
     * @Autor : xiongjinpeng  jpx_011@163.com
     * @Date : 2017年11月10日 下午1:45:21
     */
    public static int getDayOfWeek() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (week == 0) {
            week = 7;
        }
        return week;
    }

    /**
     * default pattern {@value #DATETIME}
     *
     * @param date
     * @return
     */
    public static String format(Date date) {
        if (date != null) {
            return dateTimeFormatter.format(date);
        } else {
            return null;
        }
    }

    /**
     * 获取一个没有格式，顺序排列的日期时间字符串。
     *
     * @return
     */
    public static String getCurrentDateTimeWithOutFormat() {
        return new SimpleDateFormat(DATETIMEOUT).format(new Date());
    }

    public static Date getCurrentDateWithoutHour(Date day) {
        return parse("yyyy-MM-dd", new SimpleDateFormat("yyyy-MM-dd").format(day));
    }

    /**
     * default pattern {@value #DATETIME}
     *
     * @param source
     * @return
     */
    public static Date parse(String source) {
        return parse(DATETIME, source);
    }

    public static Date parse(String pattern, String source) {
        try {
            if (source == null || "".equals(source)) {
                return null;
            }
            if (pattern == null || "".equals(pattern)) {
                return dateTimeFormatter.parse(source);
            }
            return new SimpleDateFormat(pattern).parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String format(String pattern, Date date) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 判断两个日期之间的差距 return 相差的毫秒数
     */
    public static long timeBetween(Date arg1, Date arg2) {
        if (arg1 == null || arg2 == null) {
            return 0;
        }
        if (arg1.before(arg2)) {
            return arg2.getTime() - arg1.getTime();
        } else {
            return arg1.getTime() - arg2.getTime();
        }
    }

    /**
     * 判断两个日期之间的差距 return 相差的天数
     */
    public static long dayBetween(Date arg1, Date arg2) {
        return timeBetween(arg1, arg2) / MILLIS_IN_DAY;
    }

    /**
     * 判断date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        //同一年
        if (year1 != year2) {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                //闰年
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
                    timeDistance += 366;
                } else //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else //不同年
        {
            System.out.println("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        }
    }

    /**
     * arg1是否在arg2和arg3之间
     *
     * @param arg1
     * @param arg2
     * @param arg3
     * @return
     */
    public static boolean between(Date arg1, Date arg2, Date arg3) {
        return arg1.equals(arg2) || arg1.equals(arg3) || (arg1.after(arg2) && arg1.before(arg3));
    }

    /**
     * 是否周末
     *
     * @param arg
     * @return
     */
    public static boolean isWeekend(Date arg) {
        String str = format("E", arg);
        return weekend.contains(str) ? true : false;
    }

    /**
     * 通过生日获取年龄
     *
     * @param birthday
     * @return
     */
    public static Integer getAge(Date birthday) {
        if (birthday == null)
            return null;
        Calendar cal = Calendar.getInstance();

        if (cal.before(birthday)) {
            throw new IllegalArgumentException("出生时间大于当前时间!");
        }

        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH) + 1;// 注意此处，如果不加1的话计算结果是错误的
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthday);

        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                // monthNow==monthBirth
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                } else {
                    // do nothing
                }
            } else {
                // monthNow>monthBirth
                age--;
            }
        } else {
            // monthNow<monthBirth
            // donothing
        }
        return age;
    }

    /**
     * 排序
     *
     * @param list
     * @param order
     */
    public static void sort(List<Date> list, String order) {
        if (list == null || list.size() == 0)
            return;
        if (order == null)
            order = ASC;
        Collections.sort(list);
        if (DESC.equals(order)) {
            List<Date> result = new ArrayList<Date>();
            for (int i = list.size(); i > 0; i--) {
                result.add(list.get(i - 1));
            }
            list.clear();
            list.addAll(result);
        }
    }

    /**
     * 排序
     *
     * @param list
     */
    public static void sort(List<Date> list) {
        sort(list, ASC);
    }

    public static boolean isBeforeToday(Date arg) {
        return arg.before(getTodayStartTime());
    }

    /**
     * N个小时之前
     *
     * @param arg
     * @return
     */
    public static boolean isBeforeHour(int hour, Date arg) {
        return arg.before(getLastHourTime(hour));
    }

    public static boolean isAfterToday(Date arg) {
        return arg.after(parse(format("yyyy-MM-dd", new Date()) + " 23:59:59"));
    }

    /**
     * 获得本周一的日期
     *
     * @return
     */
    public static Date getMondayOFWeek() {
        return getMondayOFWeek(0);
    }

    /**
     * 获得(本周一+day)的日期
     *
     * @return
     */
    public static Date getMondayOFWeek(int day) {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + day);
        currentDate.set(Calendar.HOUR, 0);
        currentDate.set(Calendar.SECOND, 0);
        currentDate.set(Calendar.MINUTE, 0);
        Date monday = currentDate.getTime();
        return monday;
    }

    /**
     * 获取当月第一天
     *
     * @return
     */
    public static Date getFirstDayOfMonth() {
        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MINUTE, 0);
        return lastDate.getTime();
    }

    public static boolean isFirstDayOfMonth() {
        Calendar lastDate = Calendar.getInstance();
        int day = lastDate.get(Calendar.DAY_OF_MONTH);
        return day == 1 ? true : false;
    }

    /**
     * 获取某一天最后一秒
     *
     * @param date
     * @return
     */
    public static long getLastSecondOfDay(Date date) {
        Calendar lastDate = Calendar.getInstance();
        lastDate.setTime(date);
        lastDate.set(Calendar.HOUR_OF_DAY, 23);
        lastDate.set(Calendar.SECOND, 59);
        lastDate.set(Calendar.MINUTE, 59);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTimeInMillis();
    }

    /**
     * 获取最后一秒返回日期类型
     *
     * @param date
     * @return
     * @Autor : xiongjinpeng  jpx_011@163.com
     * @Date : 2016年11月24日 上午10:08:03
     */
    public static Date getLastSecondDateOfDay(Date date) {
        Calendar lastDate = Calendar.getInstance();
        lastDate.setTime(date);
        lastDate.set(Calendar.HOUR_OF_DAY, 23);
        lastDate.set(Calendar.SECOND, 59);
        lastDate.set(Calendar.MINUTE, 59);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    /**
     * 获取月的最后一天
     *
     * @param date
     * @return
     * @Autor : xiongjinpeng  jpx_011@163.com
     * @Date : 2017年4月10日 下午3:30:41
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar lastDate = Calendar.getInstance();
        lastDate.setTime(date);
        lastDate.add(Calendar.MONTH, 1);
        lastDate.add(Calendar.DAY_OF_MONTH, -1);
        return getLastSecondDateOfDay(lastDate.getTime());
    }

    /**
     * 获取月的第一天
     *
     * @param date
     * @return
     * @Autor : xiongjinpeng  jpx_011@163.com
     * @Date : 2017年4月10日 下午3:30:44
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return getFirstSecondDateOfDay(calendar.getTime());
    }

    /**
     * 获取当年的第一天
     *
     * @return
     */
    public static Date getCurrYearFirst() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }

    /**
     * 获取当年的最后一天
     *
     * @return
     */
    public static Date getCurrYearLast() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }

    /**
     * 获取某年第一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        Date currYearLast = calendar.getTime();

        return currYearLast;
    }

    public static long getLastSecondOfDay(long date) {
        Calendar lastDate = Calendar.getInstance();
        lastDate.setTimeInMillis(date);
        lastDate.set(Calendar.HOUR_OF_DAY, 23);
        lastDate.set(Calendar.SECOND, 59);
        lastDate.set(Calendar.MINUTE, 59);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTimeInMillis();
    }

    /**
     * 获取某一天第一秒
     *
     * @param date
     * @return
     */
    public static long getFirstSecondOfDay(Date date) {
        Calendar lastDate = Calendar.getInstance();
        lastDate.setTime(date);
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTimeInMillis();
    }


    /**
     * 返回日期类型
     *
     * @param date
     * @return
     * @Autor : xiongjinpeng  jpx_011@163.com
     * @Date : 2017年4月5日 下午3:45:06
     */
    public static Date getFirstSecondDateOfDay(Date date) {
        Calendar lastDate = Calendar.getInstance();
        lastDate.setTime(date);
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTime();
    }

    public static long getFirstSecondOfDay(long date) {
        Calendar lastDate = Calendar.getInstance();
        lastDate.setTimeInMillis(date);
        lastDate.set(Calendar.HOUR_OF_DAY, 0);
        lastDate.set(Calendar.SECOND, 0);
        lastDate.set(Calendar.MINUTE, 0);
        lastDate.set(Calendar.MILLISECOND, 0);
        return lastDate.getTimeInMillis();
    }

    /**
     * 获得本年第一天的日期
     *
     * @return
     */
    public static Date getCurrentYearFirst() {
        int yearPlus = getYearPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, yearPlus);
        currentDate.set(Calendar.HOUR, 0);
        currentDate.set(Calendar.SECOND, 0);
        currentDate.set(Calendar.MINUTE, 0);
        Date yearDay = currentDate.getTime();
        return yearDay;
    }

    // 获得当前日期与本周日相差的天数
    private static int getMondayPlus() {
        Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
        // 2011.12.25 ls add
        if (dayOfWeek == 0) {// 此处为本人添加
            dayOfWeek = 7;
        }
        if (dayOfWeek == 1) {
            return 0;
        } else {
            return 1 - dayOfWeek;
        }
    }

    private static int getYearPlus() {
        Calendar cd = Calendar.getInstance();
        int yearOfNumber = cd.get(Calendar.DAY_OF_YEAR);// 获得当天是一年中的第几天
        cd.set(Calendar.DAY_OF_YEAR, 1);// 把日期设为当年第一天
        cd.roll(Calendar.DAY_OF_YEAR, -1);// 把日期回滚一天。
        int MaxYear = cd.get(Calendar.DAY_OF_YEAR);
        if (yearOfNumber == 1) {
            return -MaxYear;
        } else {
            return 1 - yearOfNumber;
        }
    }

    /**
     * 获取当天开始时时间
     *
     * @return
     */
    public static Date getTodayStartTime() {
        return parse(format(YYYYMMDD, new Date()) + " 0:00:00");
    }

    /**
     * 获取hour小时之前的时间
     *
     * @return
     */
    public static Date getLastHourTime(int hour) {
        Calendar cd = Calendar.getInstance();
        cd.add(Calendar.HOUR, -hour);
        return cd.getTime();
    }

    public static Date getLastDayTime(Date date, int day) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.DATE, -day);
        return cd.getTime();
    }

    public static Date addDay(Date date, int day) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.DATE, day);
        return cd.getTime();
    }

    public static Date addSecond(Date date, int num) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.SECOND, num);
        return cd.getTime();
    }

    public static Date getDayNoHours(Date date) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.set(Calendar.YEAR, cd.get(Calendar.YEAR));
        cd.set(Calendar.MONTH, cd.get(Calendar.MONTH));
        cd.set(Calendar.DATE, cd.get(Calendar.DATE));
        cd.set(Calendar.HOUR_OF_DAY, 0);
        cd.set(Calendar.SECOND, 0);
        cd.set(Calendar.MINUTE, 0);
        cd.set(Calendar.MILLISECOND, 0);
        return cd.getTime();
    }

    /**
     * 根据开始时间，集合时间，修正为当天的集合时间
     *
     * @param sd
     * @param gt
     * @return
     * @Autor : xiongjinpeng  jpx_011@163.com
     * @Date : 2017年8月1日 下午5:37:20
     */
    public static Date getDayByStartDate(Date sd, Date gt) {
        Calendar gtt = Calendar.getInstance();
        gtt.setTime(gt);

        Calendar sdt = Calendar.getInstance();
        sdt.setTime(sd);
        sdt.set(Calendar.HOUR_OF_DAY, gtt.get(Calendar.HOUR_OF_DAY));
        sdt.set(Calendar.MINUTE, gtt.get(Calendar.MINUTE));
        return sdt.getTime();
    }

    public static Date getLastHourTime(long time, int hour) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(new Date(time));
        cd.add(Calendar.HOUR, -hour);
        return cd.getTime();
    }

    public static Date addHour(long time, int hour) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(new Date(time));
        cd.add(Calendar.HOUR_OF_DAY, hour);
        return cd.getTime();
    }

    /**
     * 获取minitue小时之前的时间
     *
     * @return
     */
    public static Date getLastMinitueTime(int minutes) {
        Calendar cd = Calendar.getInstance();
        cd.add(Calendar.MINUTE, -minutes);
        return cd.getTime();
    }

    // 字母 日期或时间元素 表示 示例
    // G Era 标志符 Text AD
    // y 年 Year 1996; 96
    // M 年中的月份 Month July; Jul; 07
    // w 年中的周数 Number 27
    // W 月份中的周数 Number 2
    // D 年中的天数 Number 189
    // d 月份中的天数 Number 10
    // F 月份中的星期 Number 2
    // E 星期中的天数 Text Tuesday; Tue
    // a Am/pm 标记 Text PM
    // H 一天中的小时数（0-23） Number 0
    // k 一天中的小时数（1-24） Number 24
    // K am/pm 中的小时数（0-11） Number 0
    // h am/pm 中的小时数（1-12） Number 12
    // m 小时中的分钟数 Number 30
    // s 分钟中的秒数 Number 55
    // S 毫秒数 Number 978
    // z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
    // Z 时区 RFC 822 time zone -0800

    /**
     * 本地时间转换为世界标准时间UTC
     *
     * @return 世界标准时间UTC
     */
    public static String generateUTC(Date date) {
        SimpleDateFormat f = new SimpleDateFormat(DATETIME_UTC);
        return date == null ? "" : f.format(date);
    }

    /**
     * 世界标准时间UTC转换为本地时间
     *
     * @param utcTime 时间格式："yyyy-MM-dd'T'HH:mm:ss'Z'"
     * @return
     * @throws ParseException
     */
    public static Date parseUTC(String utcTime)
            throws ParseException {
        if (null == utcTime || utcTime.isEmpty()) {
            return null;
        }

        SimpleDateFormat f = null;

        String rexp = "\\d{4}\\-\\d{2}\\-\\d{2}T\\d{2}:\\d{2}:\\d{2}.[0-9]{1,3}Z";
        Pattern pat = Pattern.compile(rexp);
        Matcher mat = pat.matcher(utcTime);
        if (mat.matches()) {
            f = new SimpleDateFormat(DATETIME_UTC_FULL);
        } else {
            f = new SimpleDateFormat(DATETIME_UTC);
        }
        return f.parse(utcTime);
    }

    public static long utc2local(long utc) {
        return utc + TimeZone.getDefault().getRawOffset();
    }

    public static long local2utc(long localTime) {
        return localTime - TimeZone.getDefault().getRawOffset();
    }

    /**
     * 判断二个时间是否为同一天
     **/
    public static boolean isSameDayOfMillis(final long ms1, final long ms2) {
        final long interval = ms1 - ms2;
        return interval < MILLIS_IN_DAY && interval > -1L * MILLIS_IN_DAY && toDay(ms1) == toDay(ms2);
    }

    private static long toDay(long millis) {
        return (millis + TimeZone.getDefault().getOffset(millis)) / MILLIS_IN_DAY;
    }

    /**
     * 判断时间是否为毫秒型。
     *
     * @param time 时间
     * @return 是：返回true ， 否：返回false
     */
    public static boolean isMillis(Long time) {
        if (time != null && time > 10000000000L) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据身份证获取生日 【yyyy-MM-dd】
     *
     * @param idCard
     * @return
     */
    public static String getBirthday(String idCard) {
        if (idCard == null) {
            return null;
        }
        Pattern p1 = Pattern.compile("\\d{6}(\\d{8}).*"); // 用于提取出生日字符串
        Pattern p2 = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})");// 用于将生日字符串进行分解为年月日

        Matcher matcher = p1.matcher(idCard);
        if (matcher.find()) {
            String birthday = matcher.group(1);
            Matcher matcher2 = p2.matcher(birthday);
            if (matcher2.find()) {
                StringBuilder sb = new StringBuilder();
                sb.append(matcher2.group(1));
                sb.append('-');
                sb.append(matcher2.group(2));
                sb.append('-');
                sb.append(matcher2.group(3));
                return sb.toString();
            }
        }

        return null;
    }

    /**
     * 根据日期与时间字符串，返回时间
     *
     * @param date
     * @param timeStr
     * @return
     */
    public static long getTimeByDateAndTimeStr(Date date, String timeStr) {
        if (date != null) {
            if (StringUtil.isEmpty(timeStr)) {
                return date.getTime();
            }
            String dateStr = format(YYYYMMDD, date) + " " + timeStr;
            Date newDate = parse(DATETIME, dateStr);
            if (newDate != null) {
                return newDate.getTime();
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    /**
     * 根据日期与时间字符串，返回时间
     *
     * @param date
     * @param timeStr
     * @return
     */
    public static Date getDateByDateAndTimeStr(Date date, String timeStr) {
        if (date != null) {
            if (StringUtil.isEmpty(timeStr)) {
                return date;
            }
            String dateStr = format(YYYYMMDD, date) + " " + timeStr;
            Date newDate = parse(DATETIME, dateStr);
            return newDate;
        } else {
            return null;
        }
    }

    public static String getSection20Sec() {
        Date cur = new Date();
        Calendar cd = Calendar.getInstance();
        cd.setTime(cur);
        String s = format("yyyy-MM-dd-HH-mm", cur);
        int sec = cd.get(Calendar.SECOND);
        int ss = 1;//sec>=0&&sec<20
        if (sec >= 20 && sec < 40) {
            ss = 2;
        } else if (sec >= 40 && sec <= 60) {
            ss = 2;
        }
        s = s + "-" + ss;
        return s;
    }

    public static String getSection1Min() {
        Date cur = new Date();
        String s = format("yyyy-MM-dd-HH-mm", cur);
        return s;
    }

    /**
     * 按不同时间单位增加时间
     *
     * @param num  增加数量
     * @param unit 单位 1-年，2-月，3-日，4-小时，5-分，6-秒，7-毫秒
     * @return
     */
    public static Date addDateByUnit(Long num, Integer unit) {
        return addDateByUnit(new Date(), num, unit);
    }

    public static Date addDateByUnit(Date date, Long num, Integer unit) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        switch (unit) {
            case 1:
                cd.add(Calendar.YEAR, num.intValue());
                break;
            case 2:
                cd.add(Calendar.MONTH, num.intValue());
                break;
            case 3:
                cd.add(Calendar.DATE, num.intValue());
                break;
            case 4:
                cd.add(Calendar.HOUR_OF_DAY, num.intValue());
                break;
            case 5:
                cd.add(Calendar.MINUTE, num.intValue());
                break;
            case 6:
                cd.add(Calendar.SECOND, num.intValue());
                break;
            case 7:
                cd.add(Calendar.MILLISECOND, num.intValue());
                break;
            default:
                cd.add(Calendar.DATE, num.intValue());
                break;
        }

        return cd.getTime();
    }

    /*
     * 毫秒转化
     */
    public static String getHmstr(long ms) {

        int ss = 1000;
        int mi = ss * 60;
        int hh = mi * 60;
        int dd = hh * 24;

        long day = ms / dd;
        long hour = (ms - day * dd) / hh;
        long minute = (ms - day * dd - hour * hh) / mi;
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        String strDay = day < 10 ? "0" + day : "" + day; // 天
        String strHour = hour < 10 ? "0" + hour : "" + hour;// 小时
        String strMinute = minute < 10 ? "0" + minute : "" + minute;// 分钟
        String strSecond = second < 10 ? "0" + second : "" + second;// 秒
        String strMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;// 毫秒
        strMilliSecond = milliSecond < 100 ? "0" + strMilliSecond : "" + strMilliSecond;

        StringBuffer str = new StringBuffer();
        if (day > 0) {
            str.append(day + "天");
        }
        if (hour > 0) {
            str.append(hour + "时");
        }
        str.append(minute + "分");
/*		if(hour == 0 && minute == 0) {
			//str.append(strSecond + "秒");
		} else {
			//str.append(minute + "分钟" + strSecond + "秒");
			str.append(minute + "分");
		}*/
        return str.toString();
    }

    /*
     * 毫秒转化时分秒毫秒
     */
    public static String formatTime(Long ms) {
        Integer ss = 1000;
        Integer mi = ss * 60;
        Integer hh = mi * 60;
        Integer dd = hh * 24;

        Long day = ms / dd;
        Long hour = (ms - day * dd) / hh + 24 * day;
        //Long minute = (ms - day * dd - hour * hh) / mi;
        Long minute = (ms - hour * hh) / mi;
        //Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        Long second = (ms - hour * hh - minute * mi) / ss;
//        Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        StringBuffer sb = new StringBuffer();
//        if(day > 0) {
//            sb.append(day+"天");
//        }
        if (hour <= 0) {
            sb.append("00:");
        } else if (hour < 10) {
            sb.append("0" + hour + ":");
        } else {
            sb.append(hour + ":");
        }
        if (minute <= 0) {
            sb.append("00:");
        } else if (minute < 10) {
            sb.append("0" + minute + ":");
        } else {
            sb.append(minute + ":");
        }
        if (second < 0) {
            sb.append(second);
        } else if (second < 10) {
            sb.append("0" + second);
        } else {
            sb.append(second);
        }
//        if(milliSecond > 0) {
//            sb.append(milliSecond+"毫秒");
//        }
        return sb.toString();
    }

    public static void main(String[] args) throws ParseException {
//      System.out.println(parseUTC("2107-01-06T06:26:08Z").getTime());
//      System.out.println(new Date(4323709568L));
//        System.out.println(getLastSecondOfDay(new Date()));
//        System.out.println(getFirstSecondOfDay(new Date()));
//        System.out.println(getLastSecondOfDay(parse("yyyy-MM-dd", "2016-07-01")));
//        System.out.println(isMillis(1471316723L));
//    	Date yestoday=DateUtil.addDay(new Date(), -1);
//		DateUtil.getFirstSecondOfDay(yestoday);
//		DateUtil.getLastSecondOfDay(yestoday);
//		System.out.println(new Date(DateUtil.getFirstSecondOfDay(yestoday)));
//		System.out.println(DateUtil.getLastSecondDateOfDay(yestoday));
//    	System.out.println(getFirstDayOfMonth());
//    	System.out.println(getFirstDayOfMonth(new Date()));
//    	System.out.println(getLastDayOfMonth(new Date()));
//    	System.out.println(getDayNoHours(new Date()));
//    	System.out.println(time2005);
//        System.out.println(getCurrYearFirst());
//        System.out.println(getCurrYearLast());

//    	Calendar lastDate = Calendar.getInstance();
//        int day=lastDate.get(Calendar.DAY_OF_MONTH);
//        System.out.println(day);

//        long insuranceStopTime = DateUtil.getTimeByDateAndTimeStr(new Date(), "22:00:00");
//        System.out.println(insuranceStopTime);
//        System.out.println((new Date()).getTime());
        System.out.println("时间： " + getHmstr(1200000));
        System.out.println("时分秒：" + formatTime(1200000l));
    }


    public static long getTimeStamp(String date, String timeZone) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
        try {
            return sdf.parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static String getTimeStamp(long time, String timeZone) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
        try {
            return sdf.format(new Date(time));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 针对时间戳返回问题，返回的带时区便宜的时间戳
     */

    public final static long getTimeByZone(Date date) {

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+:08:00"));

        int zoneOffset = cal.get(Calendar.ZONE_OFFSET);

        return date.getTime() + zoneOffset;

    }


    /**
     * @param strDate
     * @return
     */
    public static Date parseDate(String strDate) {
        return parseDate(strDate, null);
    }

    /**
     * parseDate
     *
     * @param strDate
     * @param pattern
     * @return
     */
    public static Date parseDate(String strDate, String pattern) {
        Date date = null;
        try {
            if (pattern == null) {
                pattern = YYYYMMDD;
            }
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            date = format.parse(strDate);
        } catch (Exception e) {
            logger.error("parseDate error:" + e);
        }
        return date;
    }

    /**
     * format date
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return formatDate(date, null);
    }

    /**
     * format date
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        String strDate = null;
        try {
            if (pattern == null) {
                pattern = YYYYMMDD;
            }
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            strDate = format.format(date);
        } catch (Exception e) {
            logger.error("formatDate error:", e);
        }
        return strDate;
    }

    /**
     * 取得日期：年
     *
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int year = c.get(Calendar.YEAR);
        return year;
    }

    /**
     * 取得日期：年
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        return month + 1;
    }

    /**
     * 取得日期：年
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int da = c.get(Calendar.DAY_OF_MONTH);
        return da;
    }

    /**
     * 取得当天日期是周几
     *
     * @param date
     * @return
     */
    public static int getWeekDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int week_of_year = c.get(Calendar.DAY_OF_WEEK);
        return week_of_year - 1;
    }

    /**
     * 取得一年的第几周
     *
     * @param date
     * @return
     */
    public static int getWeekOfYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int week_of_year = c.get(Calendar.WEEK_OF_YEAR);
        return week_of_year;
    }

    /**
     * getWeekBeginAndEndDate
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String getWeekBeginAndEndDate(Date date, String pattern) {
        Date monday = getMondayOfWeek(date);
        Date sunday = getSundayOfWeek(date);
        return formatDate(monday, pattern) + " - "
                + formatDate(sunday, pattern);
    }

    /**
     * 根据日期取得对应周周一日期
     *
     * @param date
     * @return
     */
    public static Date getMondayOfWeek(Date date) {
        Calendar monday = Calendar.getInstance();
        monday.setTime(date);
        monday.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
        monday.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return monday.getTime();
    }

    /**
     * 根据日期取得对应周周日日期
     *
     * @param date
     * @return
     */
    public static Date getSundayOfWeek(Date date) {
        Calendar sunday = Calendar.getInstance();
        sunday.setTime(date);
        sunday.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
        sunday.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return sunday.getTime();
    }

    /**
     * 取得月的剩余天数
     *
     * @param date
     * @return
     */
    public static int getRemainDayOfMonth(Date date) {
        int dayOfMonth = getDayOfMonth(date);
        int day = getPassDayOfMonth(date);
        return dayOfMonth - day;
    }

    /**
     * 取得月已经过的天数
     *
     * @param date
     * @return
     */
    public static int getPassDayOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 取得月天数
     *
     * @param date
     * @return
     */
    public static int getDayOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 取得月第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDateOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
        return c.getTime();
    }

    /**
     * 取得月最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDateOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return c.getTime();
    }

    /**
     * 取得季度第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDateOfSeason(Date date) {
        return getFirstDateOfMonth(getSeasonDate(date)[0]);
    }

    /**
     * 取得季度最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDateOfSeason(Date date) {
        return getLastDateOfMonth(getSeasonDate(date)[2]);
    }

    /**
     * 取得季度天数
     *
     * @param date
     * @return
     */
    public static int getDayOfSeason(Date date) {
        int day = 0;
        Date[] seasonDates = getSeasonDate(date);
        for (Date date2 : seasonDates) {
            day += getDayOfMonth(date2);
        }
        return day;
    }

    /**
     * 取得季度剩余天数
     *
     * @param date
     * @return
     */
    public static int getRemainDayOfSeason(Date date) {
        return getDayOfSeason(date) - getPassDayOfSeason(date);
    }

    /**
     * 取得季度已过天数
     *
     * @param date
     * @return
     */
    public static int getPassDayOfSeason(Date date) {
        int day = 0;

        Date[] seasonDates = getSeasonDate(date);

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);

        if (month == Calendar.JANUARY || month == Calendar.APRIL
                || month == Calendar.JULY || month == Calendar.OCTOBER) {// 季度第一个月
            day = getPassDayOfMonth(seasonDates[0]);
        } else if (month == Calendar.FEBRUARY || month == Calendar.MAY
                || month == Calendar.AUGUST || month == Calendar.NOVEMBER) {// 季度第二个月
            day = getDayOfMonth(seasonDates[0])
                    + getPassDayOfMonth(seasonDates[1]);
        } else if (month == Calendar.MARCH || month == Calendar.JUNE
                || month == Calendar.SEPTEMBER || month == Calendar.DECEMBER) {// 季度第三个月
            day = getDayOfMonth(seasonDates[0]) + getDayOfMonth(seasonDates[1])
                    + getPassDayOfMonth(seasonDates[2]);
        }
        return day;
    }

    /**
     * 取得季度月
     *
     * @param date
     * @return
     */
    public static Date[] getSeasonDate(Date date) {
        Date[] season = new Date[3];

        Calendar c = Calendar.getInstance();
        c.setTime(date);

        int nSeason = getSeason(date);
        if (nSeason == 1) {// 第一季度
            c.set(Calendar.MONTH, Calendar.JANUARY);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.FEBRUARY);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.MARCH);
            season[2] = c.getTime();
        } else if (nSeason == 2) {// 第二季度
            c.set(Calendar.MONTH, Calendar.APRIL);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.MAY);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.JUNE);
            season[2] = c.getTime();
        } else if (nSeason == 3) {// 第三季度
            c.set(Calendar.MONTH, Calendar.JULY);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.AUGUST);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.SEPTEMBER);
            season[2] = c.getTime();
        } else if (nSeason == 4) {// 第四季度
            c.set(Calendar.MONTH, Calendar.OCTOBER);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.NOVEMBER);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.DECEMBER);
            season[2] = c.getTime();
        }
        return season;
    }

    /**
     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
     *
     * @param date
     * @return
     */
    public static int getSeason(Date date) {

        int season = 0;

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }
        return season;
    }

    public static Date getTime(int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        Date time = calendar.getTime();
        return time;
    }

    /**
     * 取得季度天数
     *
     * @param date
     * @return
     */
    public static Calendar dateToCalendar(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }

    /**
     * 取得当前年一月一号时间戳
     *
     * @return
     */
    public static Long getYearStartTime() {

        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    public static String timeStamp2DateTime(Long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//要转换的时间格式
        Date date;
        try {
            date = sdf.parse(sdf.format(time));
            return sdf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String timeStamp2Date(Long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//要转换的时间格式
        Date date;
        try {
            date = sdf.parse(sdf.format(time));
            return sdf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String timeStamp2DateBeforeDay(Long timeStamp, int beforyDay) {
        Calendar cal = Calendar.getInstance();
        Date date1 = new Date(timeStamp);
        cal.setTime(date1);
        cal.add(Calendar.DAY_OF_MONTH, -beforyDay);
        return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
    }


    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static boolean isEffectiveDate(String nowTime, String startTime, String endTime) {
        Date newDate = parseDate(nowTime, DATETIME);
        Date startDate = parseDate(startTime, DATETIME);
        Date endDate = parseDate(endTime, DATETIME);
        return isEffectiveDate(newDate, startDate, endDate);
    }


    public static Long[] timeStamp2DateBeforeDay(Long startDate, Long endDate, int space) {

        return null;
    }

    /**
     * parseDate
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String parseDateStr(String date, String pattern) {

        try {
            SimpleDateFormat format = new SimpleDateFormat(pattern);

            Date parse = format.parse(date);
            String sd = format.format(parse);
            return sd;
        } catch (Exception e) {
            logger.error("parseDate error:" + e);
        }
        return null;
    }


}
